package com.fary.boot.autoconfigure.security.servlet;

import com.fary.boot.autoconfigure.AutoConfigureAfter;
import com.fary.boot.autoconfigure.condition.ConditionalOnBean;
import com.fary.boot.autoconfigure.condition.ConditionalOnClass;
import com.fary.boot.autoconfigure.condition.ConditionalOnWebApplication;
import com.fary.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import com.fary.boot.context.properties.EnableConfigurationProperties;
import com.fary.context.annotation.Bean;
import com.fary.context.annotation.Configuration;
import sun.security.util.SecurityProperties;

import java.util.EnumSet;
import java.util.stream.Collectors;

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SecurityProperties.class)
@ConditionalOnClass({ AbstractSecurityWebApplicationInitializer.class, SessionCreationPolicy.class })
@AutoConfigureAfter(SecurityAutoConfiguration.class)
public class SecurityFilterAutoConfiguration {

	private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;

	@Bean
	@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
	public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
			SecurityProperties securityProperties) {
		DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
				DEFAULT_FILTER_NAME);
		registration.setOrder(securityProperties.getFilter().getOrder());
		registration.setDispatcherTypes(getDispatcherTypes(securityProperties));
		return registration;
	}

	private EnumSet<DispatcherType> getDispatcherTypes(SecurityProperties securityProperties) {
		if (securityProperties.getFilter().getDispatcherTypes() == null) {
			return null;
		}
		return securityProperties.getFilter().getDispatcherTypes().stream()
				.map((type) -> DispatcherType.valueOf(type.name()))
				.collect(Collectors.toCollection(() -> EnumSet.noneOf(DispatcherType.class)));
	}

}